package org.atf.command;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.log4j.Logger;




public class AtfLocal{
	private  static Logger  logger = Logger.getLogger(AtfLocal.class);
	private StringBuffer outputBuffer;
	private StringBuffer errorBuffer;
	private String command;
	private Map<String, String> env;
	private String arguments;
	private int errorCode=-1;
	private boolean running = false;
	
	public AtfLocal() {
		// TODO Auto-generated constructor stub
	}
	
	public  void localExecute() throws IOException, InterruptedException{
		logger.info("Running the script: local ");
		String[] envp= null;
		ArrayList<String> envpList= new ArrayList<String>();
		if(env != null){
			Iterator keys=env.keySet().iterator();
			while(keys.hasNext()){
				String name=(String)keys.next();
				String value=env.get(name);
				logger.debug("Name: "+name+" /Value: "+value);
				envpList.add(name+"="+value);
			}
		}
		
		envp=envpList.toArray(new String[envpList.size()]);
		
		command+=" "+arguments;
		running=true;
		Process process = Runtime.getRuntime().exec(command, envp, null);
	
         InputStream stdin = process.getInputStream();
         InputStream stderr = process.getErrorStream();
         Thread tIn = new Thread(new ConsoleSimulator(stdin, getOutputBuffer(),0));
         Thread tErr = new Thread(new ConsoleSimulator(stderr, getErrorBuffer(), 1));
         tIn.start();
         tErr.start();
         int exitCode = process.waitFor();
         logger.info("Exit Code:  "+exitCode);
         setErrorCode(exitCode);
         running=false;
		
	}
	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}

	public  void localExecute(String cmd, HashMap<String,String> env, String arguments) throws IOException, InterruptedException{
		logger.info("Running the script: local ");
		String[] envp= null;
		if(env != null){
			ArrayList<String> envpList= new ArrayList<String>();
			Iterator keys=env.keySet().iterator();
			while(keys.hasNext()){
				String name=(String)keys.next();
				String value=env.get(name);
				logger.debug("Name: "+name+" /Value: "+value);
				envpList.add(name+"="+value);
			}
			envp=envpList.toArray(new String[envpList.size()]);
			
			cmd+=" "+arguments;
			running=true;
			Process process = Runtime.getRuntime().exec(cmd, envp, null);
		
             InputStream stdin = process.getInputStream();
             InputStream stderr = process.getErrorStream();
             Thread tIn = new Thread(new ConsoleSimulator(stdin, getOutputBuffer(),0));
             Thread tErr = new Thread(new ConsoleSimulator(stderr, getErrorBuffer(), 1));
             tIn.start();
             tErr.start();
             int exitCode = process.waitFor();
             setErrorCode(exitCode);
             running=false;
		}
		
	}
	
	public boolean checkIfDirExists(String path){
		File localDir = new File(path);
		if (localDir.exists()) {
			return true;
		}
		return false;
	}
	public void deleteIfDirExists(String path) {
		// TODO Auto-generated method stub
		if (checkIfDirExists(path)) {
			logger.info("Deleting directory: " +path );
			File localDir = new File(path);
			localDir.delete();
			logger.info("Deleted Ok");
		}
	}
	public void createDirIfNotExists(String path) {
		// TODO Auto-generated method stub
		if (!checkIfDirExists(path)) {
			logger.info("creating directory: " +path );
			try{
				File localDir = new File(path);
				localDir.mkdir();
				logger.info("Created Ok");
		     } catch(SecurityException se){
		        //handle it
		    	 logger.error(se.getMessage());
		     }   
		}
	}
	public List<String> getDirectoryList(String responseFilesPath) {
		// TODO Auto-generated method stub
		logger.info("getDirectoryList : responseFilesPath: "+responseFilesPath);
		List<String> lists= new ArrayList<String>();
		if (checkIfDirExists(responseFilesPath)) {
			File dir = new File(responseFilesPath);
			File[] subdirs = dir.listFiles((FileFilter) DirectoryFileFilter.DIRECTORY);
			logger.debug("subdirs:"+subdirs);
			for (File dirN : subdirs) {
				logger.debug("Directory: " + dirN.getName());
				lists.add(dirN.getName());
			}
		}
		return lists;
	}
	public void copy(File src, File dst) throws IOException {
	    InputStream in = new FileInputStream(src);
	    OutputStream out = new FileOutputStream(dst);

	    // Transfer bytes from in to out
	    byte[] buf = new byte[1024];
	    int len;
	    while ((len = in.read(buf)) > 0) {
	        out.write(buf, 0, len);
	    }
	    in.close();
	    out.close();
	}

	public StringBuffer getOutputBuffer() {
		 if(outputBuffer == null)
			 outputBuffer = new StringBuffer();
	        return outputBuffer;
	}

	public void setOutputBuffer(StringBuffer outputBuffer) {
		this.outputBuffer = outputBuffer;
	}

	public StringBuffer getErrorBuffer() {
		if(errorBuffer == null)
			errorBuffer = new StringBuffer("");
       return errorBuffer;
	}

	public void setErrorBuffer(StringBuffer errorBuffer) {
		this.errorBuffer = errorBuffer;
	}

	public int getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(int errorCode) {
		this.errorCode = errorCode;
	}
	public void clearOutput(){
		outputBuffer = null;
	}
	public void clearError(){
		errorBuffer = null;
	}

	public String getCommand() {
		return command;
	}

	public void setCommand(String command) {
		this.command = command;
	}

	public Map<String, String> getEnv() {
		return env;
	}

	public void setEnv(Map<String, String> env) {
		this.env = env;
	}

	public String getArguments() {
		return arguments;
	}

	public void setArguments(String arguments) {
		this.arguments = arguments;
	}

	

	

	
	
}
